﻿// Copyright (c) 2017 GlassGrass

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UniRx;
using UnityEngine;

namespace GlassGrass.Unity.GuiFramework
	{
	/// <summary> Holdable button. </summary>
	public class RepeatButton : GuiElement
		{
		#region events

		private readonly Subject<bool> _pushInternal;

		/// <summary> Be fired when this was pressed. </summary>
		public IObservable<EventArgs> Pressed => _pressed;
		private readonly Subject<EventArgs> _pressed = new Subject<EventArgs>();

		/// <summary> Be fired when this was released. </summary>
		public IObservable<EventArgs> Released => _released;
		private readonly Subject<EventArgs> _released = new Subject<EventArgs>();

		#endregion



		#region fields and properties

		/// <summary> [get] Button holding state. </summary>
		public bool Holding
			{
			get => _buttonHolding;
			private set
				{
				_buttonHolding = value;
				_pushInternal.OnNext(value);
				}
			}
		private bool _buttonHolding = false;

		#endregion



		/// <summary> Create RepeatButton instance. </summary>
		/// <param name="config"> [Non-Nullable] </param>
		/// <exception cref="System.ArgumentNullException"></exception>
		public RepeatButton(GuiConfig config)
			: base( config )
			{
			_pushInternal = new Subject<bool>();
			var stateChanged = _pushInternal.DistinctUntilChanged();
			stateChanged.Where( pushing => pushing )
				.Select( _ => EventArgs.Empty )
				.Subscribe( _pressed );
			stateChanged.Where( pushing => !pushing )
				.Select( _ => EventArgs.Empty )
				.Subscribe( _released );
			}



		/// <summary> Define what to choose style for this from skin. </summary>
		/// <param name="skin"></param>
		/// <returns></returns>
		protected override GUIStyle ChooseStyle(GUISkin skin)
			=> skin?.button;



		/// <summary> Define how to layout manually itself on rendering frame. </summary>
		/// <param name="parentSkin"></param>
		public override void LayoutManual(GUISkin parentSkin)
			{
			Holding = GUI.RepeatButton( Rect, Content, SelectValidStyle( parentSkin ) ) ;
			}



		/// <summary> Define how to layout automatically itself on rendering frame.  </summary>
		/// <param name="parentSkin"></param>
		public override void LayoutAuto(GUISkin parentSkin)
			{
			Holding = GUILayout.RepeatButton( Content, SelectValidStyle( parentSkin ), LayoutOptions );
			}

		}
	}
